package com.nc.mem.serial.graph.boot;

import java.util.ServiceLoader;

import org.slf4j.LoggerFactory;

public abstract class ProvisionServiceFactory {

	/**
	 * Attempts to resolve a list of provision services by instantiating a
	 * {@link ProvisionServiceFactory} with fully qualified name labeled context and if found, it
	 * will call {@link ProvisionServiceFactory#getProvisionServices()}. Otherwise it will use the
	 * {@link ServiceLoader#load(Class)} to look for services on the classpath.
	 * 
	 * @param context
	 * @return
	 */
	public static Iterable<ProvisionService> resolveOrFallback(final String context) {

		ProvisionServiceFactory fac = null;

		final String cn = context == null || !context.trim().isEmpty() ? null : context;

		if (cn != null) {
			try {
				final Class<?> facClass = Class.forName(context);

				if (facClass.isAssignableFrom(ProvisionServiceFactory.class)) {
					fac = (ProvisionServiceFactory) facClass.newInstance();
				}
			} catch (final Throwable err) {
				LoggerFactory.getLogger(ProvisionServiceFactory.class).warn("Could not create {} from class {}", ProvisionServiceFactory.class.getName(), cn);
			}
		}

		return fac == null ? ServiceLoader.load(ProvisionService.class) : fac.getProvisionServices();
	}

	protected abstract Iterable<ProvisionService> getProvisionServices();

}
